/*
 * icr.c
 * Project 4
 * Nicole Ang (nang1@asu.edu)
 * Bijan Fakhri (bfakhri@asu.edu)
 * CSE 325: Embedded Microprocessor Systems
 * Spring 2013
 */

#include "intcr.h"

extern uint32 __VECTOR_RAM[];

#define ICR_BASE (volatile uint8 *)(0x40000C40)

void intcr_config(int p_src, int p_level, int p_priority, isr_funct p_isr){
	volatile uint8 *icr;
	
	/* Write the address of the ISR (in p_isr) into the exception vector table at the proper offset from the beginning of the table.
	*/
	__VECTOR_RAM[64 + p_src] = (uint32)p_isr;

	/* Write the level and priority for the interrupt source into the appropriate ICR register. */
	icr = (volatile uint8 *)(ICR_BASE + p_src);
	*icr = (uint8)(p_level << 3 | p_priority);

	/* Unmask interrupts from the interrupt source. */
	intcr_unmask_src(p_src);
}

void intcr_unmask_src(int p_src){
	/* The mask bits for interrupt sources 32-63 are in the IMRH registers. The mask bits for interrupt sources 1-31 are in the IMRL registers. Note, when clearing bits in IMRL it is important not to write 1 to IMRL[0] because this is the MASKALL bit.
	*/

	if (p_src > 31) {
		MCF_INTC0_IMRH &= ~(1 << (p_src - 32));
	} else {
		MCF_INTC0_IMRL &= ~(1 << p_src) & 0xFFFFFFFE;
	}
}